package com.qf.springbootdemo03.config;

import com.qf.springbootdemo03.service.MyUserDetailService;
import com.qf.springbootdemo03.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author q
 * @version V1.0
 * @date 2021/11/25
 **/
@Configuration
public class SecurityConfig02 extends WebSecurityConfigurerAdapter {

    @Autowired
    //MyUserDetailService myUserDetailService;
    UserService userService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在认证得过程中是需要指定加密器对象，因为会使用这个加密器对象去对原始密码和数据库密码进行比对
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
    }

    /**
     * 配置请求的相关信息
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //super.configure(http);
        //指定未授权页面资源，独立配置
        http.exceptionHandling().accessDeniedPage("/403.html");
        http
            //登录相关配置
            //凡是 url，必须以 / 开头
            .formLogin()
                //指定登录页
                .loginPage("/login.html")
                /*//配置登录表单用户名与密码
                用户名:<input type="text" name="uname"/><br>
                密  码:<input type="text" name="password"/><br>
                .usernameParameter("uname").passwordParameter("password")*/
                //登录请求的url
                .loginProcessingUrl("/user/login")
                //登录成功后
                // 如果有指定访问的目标资源，那么就跳指定资源
                // 如果直接访问登录页，那么就跳success
                .defaultSuccessUrl("/success")
                //经过上面的过程，就放行
                .permitAll()
            //另开一个配置，就以and开头
            .and()
                //配置拦截资源： 匹配/、/hello 无需认证就能访问
                .authorizeRequests().antMatchers("/", "/hello", "/showname").permitAll()
            //所有的请求都需要认证通过才能访问
            .and().authorizeRequests().anyRequest().authenticated()//.hasAnyRole("manager", "user")放行 ROLE_manager和 ROLE_user
            //关闭csrf[跨站伪造请求]，security认为不用它的提供的登录页面，就是一个攻击的请求
            .and().csrf().disable();
    }
}
